/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.logiclander.ricemine.services.identity;

import com.logiclander.ricemine.utils.LdapUtilities;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.kuali.rice.kim.bo.entity.dto.KimEntityResidencyInfo;
import org.springframework.ldap.core.ContextMapper;
import org.springframework.ldap.core.DirContextAdapter;

/**
 *
 * @author tcarroll
 */
public class LdapKimEntityResidencyInfoMapper implements ContextMapper {

  private final Log log = LogFactory.getLog(getClass());
  private String entityIdAttributeName = null;
  private String determinationMethodAttributeName = null;
  private String inStateFlagAttributeName = null;

//beg: methods required by ContextMapper interface
  public Object mapFromContext(Object ctx) {
    validateConfiguration();
    KimEntityResidencyInfo keri = new KimEntityResidencyInfo();
    try {
      DirContextAdapter context = (DirContextAdapter) ctx;

      // potential to be special or synthetic, so do some special processing
      if (context.getStringAttribute(entityIdAttributeName).equalsIgnoreCase("dn")) {
        keri.setEntityId(LdapUtilities.buildDn(context, true));
      } else if (context.getStringAttribute(entityIdAttributeName).equals("objectGUID")) {
        keri.setEntityId(LdapUtilities.buildGuid(context));
      } else {
        keri.setEntityId(context.getStringAttribute(entityIdAttributeName));
      }
      // currently, this assumes that an entity only has one residency (the one aligned
      // with this ldap record.  this is a decent assumption for now, but a configurable
      // option for either doing it this way or mapping multiple residencies would be better
      // perhaps some organizations have multi-valued attributes that list residencies

      // the id is a synthetic identifier for the instance of an entity residency.
      // this should be unique in the system, but there is no graceful way to do this
      // from an ldap mapping
      keri.setId("1");//is there an ldap attribute for this?
      keri.setDeterminationMethod(LdapUtilities.materialize(context.getStringAttribute(determinationMethodAttributeName)));
      keri.setInStateFlag(LdapUtilities.materialize(context.getStringAttribute(inStateFlagAttributeName)));
    } catch (Throwable t) {
      log.error("Error in ContextMapper", t);
      String msg = "ContextMapper failed to create a LdapRecord from the specified Context: " + ctx;
      throw new RuntimeException(msg, t);
    }
    if (log.isDebugEnabled()) {
      log.debug("mapped KimEntityResidency: entityId=" + keri.getEntityId());
    }
    return keri;
  }

//end: methods required by ContextMapper interface
//beg: helper methods
  public String getEntityIdAttributeName() {
    return this.entityIdAttributeName;
  }

  public void setEntityIdAttributeName(String attrName) {
    this.entityIdAttributeName = attrName;
  }

  public String getDeterminationMethodAttributeName() {
    return this.determinationMethodAttributeName;
  }

  public void setDeterminationMethodAttributeName(String attrName) {
    this.determinationMethodAttributeName = attrName;
  }

  public String getInStateFlagAttributeName() {
    return this.inStateFlagAttributeName;
  }

  public void setInStateFlagAttributeName(String attrName) {
    this.inStateFlagAttributeName = attrName;
  }

  private void validateConfiguration() {
    if (entityIdAttributeName == null) {
      String msg = "The property 'entityIdAttributeName' must be set.";
      throw new IllegalStateException(msg);
    }
    if (determinationMethodAttributeName == null) {
      String msg = "The property 'determinationMethodAttributeName' must be set.";
      throw new IllegalStateException(msg);
    }
    if (inStateFlagAttributeName == null) {
      String msg = "The property 'inStateFlagAttributeName' must be set.";
      throw new IllegalStateException(msg);
    }
  }
//end: helper methods
}
